/**
 * 加密算法
 *
 * Created by snowingsea on 2020/01/21.
 */
const bcrypt = require('bcryptjs');
const crypto = require('crypto');

/**
 * 加密
 * @param {String} password 原字符串
 * @param {String|Function} salt 盐
 * @return {Promise}
 */
function encrypt(password, salt = null) {
  if (!salt) {
    salt = bcrypt.genSaltSync(10);
  }

  return new Promise((resolve, reject) => {
    crypto.pbkdf2(password, salt, 100000, 64, 'sha256', (err, hash) => {
      if (hash) { hash = hash.toString('hex'); }
      err ? reject(err) : resolve({ hash, salt });
    });
  });
}

/**
 * 比较加密字符
 * @param {String} password 用户提交的密码
 * @param {String} salt 盐
 * @param {String} encryptedPassword 加密后的密码
 * @return {Promise}
 */
function compare(password, salt, encryptedPassword) {
  return new Promise((resolve, reject) => {
    encrypt(password, salt).then((value) => {
      resolve(encryptedPassword === value.hash);
    }).catch(reject);
  });
}

/**
 * 生成随机token
 * @return {Promise}
 */
function generateRandomToken() {
  return new Promise((resolve, reject) => {
    crypto.randomBytes(256, (err, buffer) => {
      let token = null;
      if (buffer) {
        token = crypto.createHash('sha1').update(buffer).digest('hex');
      }
      err ? reject(err) : resolve(token);
    });
  });
}

/**
 * Export model definition object.
 */
module.exports = {
  encrypt,
  compare,
  generateRandomToken,
};
